using System;
using System.Linq.Expressions;
using MathService.Extentions.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MathServiceTestProject
{
    [TestClass]
    public class ExpressionExtentions_Test
    {
        public TestContext TestContext { get; set; }

        #region Additional test attributes

        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion

        [TestMethod]
        public void TestSimpleFunction()
        {
            Expression<Func<double, double>> originalExpression = t => t * t * t + 20;

            Expression<Func<double, double>> substituteExpression = t => t * t;

            var modifiedExpression = originalExpression.Substitute("t", substituteExpression);

            var modifiedFunction =
               (Func<double, double>)modifiedExpression.Compile();

            Assert.AreEqual((int)modifiedFunction(1), 21);
            Assert.AreEqual((int)modifiedFunction(2), 2 * 2 * 2 * 2 * 2 * 2 + 20);
        }

        [TestMethod]
        public void TestComplexPolynomial()
        {
            Expression<Func<double, double>> originalExpression =
                t => (1 - t) * (1 - t) * (1 - t) * (-50) +
                        3 * (1 - t) * (1 - t) * t * (-25) +
                        3 * (1 - t) * t * t * 25 +
                        t * t * t * 50;

            Expression<Func<double, double, double, double>> substituteExpression = (t, factor, shift) => t * factor + shift;

            var modifiedExpression = originalExpression.Substitute("t", substituteExpression);

            var modifiedFunction =
                (Func<double, double, double, double>)modifiedExpression.Compile();

            var result = modifiedFunction(1, 10, -9);
            Assert.AreEqual(result, 50);

            Console.WriteLine(originalExpression);
            Console.WriteLine();
            Console.WriteLine(modifiedExpression);
        }
    }
}